//
//  ZLNetWorkManager.swift
//  ZLWeibo
//
//  Created by zhanglongtao on 16/12/19.
//  Copyright © 2016年 hanju001. All rights reserved.
//

import UIKit
import AFNetworking//文件夹的名字

/*
 如果日常开发中，发送网络请求返回的状态码是405 支持的网络请求方法
 首先应该检查网络请求的方法是否正确
 */
//枚举支持任意类型数据
enum ZLHttpMethod{
    
    case GET
    case POST
}
//网络管理工具
class ZLNetWorkManager: AFHTTPSessionManager {
    
    //静态去 常量 闭包 在第一次访问时执行闭包 并且将结果保存在sahred常量中
    static let shared = { () -> ZLNetWorkManager in 
        
        //实例化对象
        let instance = ZLNetWorkManager()
        
        //设置相应的反序列化 支持的数据格式的类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        //返回对象
        
        return instance
    }()
    
    
    lazy var userAcount = ZLUserAcount()
    //用户登录标记计算属性
    var userLogon: Bool{
        
        return userAcount.access_token != nil
    }
    
    
    func tokenRequest(method: ZLHttpMethod = .GET, URLString: String, parameters: [String: AnyObject]?, name: String? = nil, data: Data? = nil, completion: @escaping (_ json: AnyObject?, _ isSuccess: Bool)->()) {
        
        guard let token = userAcount.access_token else{
            
            //发送通知提示用户登录
            print("需要登录")
            //发送通知 提示用户登录
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: ZLUersShouldLoginNotigication), object: nil)
            completion(nil,false)
            return
        }
        //处理token字典
        var parateterser = parameters
        if parateterser == nil{
            
            parateterser = [String: AnyObject]()
            
        }
        parateterser?["access_token"] = token as AnyObject?
        
        //调用request发起真正的网络请求
        if let name = name, let data = data {
            upload(URLString: URLString, parameters: parameters, name: name, data: data, completion: completion)
        }else{
            request(method: method, URLString: URLString, parameters: parateterser, completion: completion)
        }
        
    }
    /// 上传文件AFN的上传文件方法 必须是post方法
    func upload(URLString: String, parameters: [String: AnyObject]?,name: String, data: Data, completion: @escaping (_ json: AnyObject?, _ isSuccess: Bool)->()) {
        
        
        post(URLString, parameters: parameters, constructingBodyWith: { (formData) in
            //fileName 一般是随便写
            //application/octet-stream默认mimeType
            formData.appendPart(withFileData: data, name: name, fileName: "xxx", mimeType: "application/octet-stream")
            
        }, progress: nil, success: { (_, json) in
            completion((json as AnyObject), true)
            
        }) { (task, error) in
            
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                print("Token 过期了")
                
                // 发送通知，提示用户再次登录(本方法不知道被谁调用，谁接收到通知，谁处理！)
                //NotificationCenter.default().post(
                //name: NSNotification.Name(rawValue: WBUserShouldLoginNotification),
                //object: "bad token")
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: ZLUersShouldLoginNotigication), object: "bad token")
            }
            
            // error 通常比较吓人，例如编号：XXXX，错误原因一堆英文！
            print("网络请求错误 \(error)")
            
            completion(nil, false)
        }
    }
    //使用一个函数封装get/post请求
    func request(method: ZLHttpMethod = .GET, URLString: String, parameters: [String: AnyObject]?, completion: @escaping (_ json: AnyObject?, _ isSuccess: Bool)->()) {
        
        
        if method == .GET {
            

            get(URLString, parameters: parameters, progress: nil, success: { (_, json) in
                
                completion((json as AnyObject), true)
                
            }, failure: { (task, error) in
                
                // 针对 403 处理用户 token 过期
                // 对于测试用户(应用程序还没有提交给新浪微博审核)每天的刷新量是有限的！
                // 超出上限，token 会被锁定一段时间
                // 解决办法，新建一个应用程序！
                if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                    print("Token 过期了")
                    
                    // 发送通知，提示用户再次登录(本方法不知道被谁调用，谁接收到通知，谁处理！)
                    //NotificationCenter.default().post(
                    //name: NSNotification.Name(rawValue: WBUserShouldLoginNotification),
                    //object: "bad token")
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: ZLUersShouldLoginNotigication), object: "bad token")
                }
                
                // error 通常比较吓人，例如编号：XXXX，错误原因一堆英文！
                print("网络请求错误 \(error)")
                
                completion(nil, false)
            })
        } else {
            
            post(URLString, parameters: parameters, progress: nil, success: { (task, json) in
                
                 completion((json as AnyObject), true)
                
            }, failure: { (task, error) in
                
                // 针对 403 处理用户 token 过期
                // 对于测试用户(应用程序还没有提交给新浪微博审核)每天的刷新量是有限的！
                // 超出上限，token 会被锁定一段时间
                // 解决办法，新建一个应用程序！
                if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                    print("Token 过期了")
                    
                    // 发送通知，提示用户再次登录(本方法不知道被谁调用，谁接收到通知，谁处理！)
                    //NotificationCenter.default().post(
                    //name: NSNotification.Name(rawValue: WBUserShouldLoginNotification),
                    //object: "bad token")
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: ZLUersShouldLoginNotigication), object: "bad token")
                }
                
                // error 通常比较吓人，例如编号：XXXX，错误原因一堆英文！
                print("网络请求错误 \(error)")
                
                completion(nil, false)
            })
        }
    }

}


